home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
130 MIDI Tool Box
/
130 MIDI Tool Box.iso
/
sda_ur22
/
sda_usr1.asm
< prev
next >
Wrap
Assembly Source File
|
1987-08-05
|
12KB
|
633 lines
page
name SDA_USER_ROUTINES
code segment public 'code'
assume cs:code,ds:code
;******************************************************************
;*
;* RELEASE 2.0
;*
;* CHANGES TO PRE-EXISTING (RELEASE 1.0) ROUTINES:
;*
;* 1. _CHECK4_SDA now alters reg. CX.
;*
;* This routine has been modified to turn off the tempo updates
;* that are active if the TSR program is invoked out of Promidi's
;* Play/Record screen.
;*
;* 2. _PREP_RTN must be called before the TSR program terminates
;* and returns. This will re-activate the tempo updates if
;* necessary.
;*
;* These changes affect only the routines in this source module.
;* Release 1.0 User Routines will continue to work (unmodified)
;* with ALL Promidi software (ver. C11 & above).
;*
;*
;*
;* NEW FEATURES
;*
;* Routines have been added that allow TSR programs to put the
;* Midicard in UART Mode and access the interface directly
;* through its I/O space.
;*
;* The UART Mode send and receive routines (_U_SNDB, _U_RCVB) are
;* many times faster than _SDA_GETB and _SDA_PUTB. They are
;* intended to be used for "longer" uploads and downloads (say more
;* than 100 bytes or so) where the ability to send and receive
;* while Promidi is playing or recording are not as important
;* as the time required for the operations.
;*
;* In UART Mode, there is no Midi Thru capability in the
;* Midicard. Any passing of data through the interface
;* (Midi In to Midi Out) must be done by the TSR software in this mode.
;*
;* UART Mode may be entered and exited on a message by message
;* basis, using _SDA_GETB and _SDA_PUTB for the shorter messages;
;* and _U_RCVB and _U_SNDB for longer ones.
;*
;* *** DANGER ***
;*
;* Only the following User Routines may be called while
;* in UART Mode:
;*
;* _U_RCVB Get a byte from the Midicard
;*
;* _U_SNDB Send a byte to the Midicard
;*
;* _SDA_UOFF Leave UART Mode
;*
;* _SDA_EXEC Call Promidi's EXEC
;*
;* To enter UART Mode, the TSR software must first call '_SDA_UON'.
;* This routine returns 0 (FAIL) if Promidi is recording or playing,
;* or the TSR software is recording ('_SDA_RECON'). In the case
;* of Promidi recording or playing, it is suggested that the
;* software notify the user that the type of operation requested
;* can not be performed while playing or recording. The user may
;* then flip back to Promidi to stop, and then return to the TSR
;* program.
;*
;******************************************************************
;******************************************************************
;*
;* See companion file 'SDA_USER.DOC' for more information on
;* these subroutines.
;*
;******************************************************************
;******************************************************************
;*
;* This software is intended to provide access to a running
;* Promidi system from co-resident software which receives
;* control via INT 16 (function 1). Two prerequisites are
;* necessary before the service routines may be called:
;* 1. The interrupting routine must immediately save the Promid's
;* DS register in _SDA_DSEG.
;* 2. The routine _CHECK4_SDA must be called successfully
;* (RET = 1). This routine binds the two programs together.
;*
;* If it is desired to have Promidi continue to read from the disk
;* (as when playing a file/track), the routine _SDA_EXEC must be
;* called periodically.
;*
;******************************************************************
;*************************************************************************
;*
;* The source file 'SDA_USER.ASM' is provided free of charge by Systems
;* Design Associates, Inc. SDA does not in any way warranty this software
;* nor is it liable for any damages resulting from its use.
;*
;*************************************************************************
PUBLIC _SDA_DSEG
_SDA_DSEG DW 0 ; SDA's Data Segment
; Must be saved by the user upon
; entrance via INT 16.
SDA_SS DW 0 ; SAVED IN SDAKI BEFORE THE INT 16.
SDA_SP DW 0
SDA_BP DW 0
SDA_SI DW 0
SDA_DI DW 0
USER_SS DW 0 ; SAVED IN THE USER ROUTINES
USER_DS DW 0 ; THAT CALL EXEC.
USER_SP DW 0
USER_BP DW 0
USER_DI DW 0
USER_ES DW 0
IRLOC2 dw (8 + 2) * 4 ; Midicard Interrupt locations.
IRLOC7 dw (8 + 7) * 4
IRLOC5 dw (8 + 5) * 4
IRLOC4 dw (8 + 4) * 4
PTA dw ? ; Midicard Port Addresses
PTB dw ?
PTC dw ?
PTCNTL dw ?
UREC_MODE db 0 ; In User Record Mode Flag
TUP_STATUS db 0 ; Tempo Update Status Flag.
PUBLIC _CHECK4_SDA,_SDA_GETB,_SDA_PUTB,_SDA_EXEC,_SDA_RECON
PUBLIC _SDA_RECOFF,_U_SNDB,_U_RCVB,_PREP_RET,_SDA_UON,_SDA_UOFF
page
; _CHECK4_SDA
;
; *** DANGER *** THIS ROUTINE MUST BE CALLED SUCCESSFULLY (RET = 1)
; IN ORDER TO USE ANY OF THE SDA USER FUNCTIONS.
;
; If SDA interface (Midicard) interrupt handler is
; in place, this routine fills SDA_SEG & SDA_OFST with the
; addr. of USER_CALL.
;
; Returns: ax = 0 Handler not present.
; ax = 1 Is present - data filled.
;
; Regs altered - ax,bx,cx,dx
_CHECK4_SDA proc far
push es
push si
push bp
mov si,[IRLOC2]
call SDA_MATCH
cmp ax,1
je GOT_MATCH
mov si,[IRLOC7]
call SDA_MATCH
cmp ax,1
je GOT_MATCH
mov si,[IRLOC5]
call SDA_MATCH
cmp ax,1
je GOT_MATCH
mov si,[IRLOC4]
call SDA_MATCH
cmp ax,1
je GOT_MATCH
xor ax,ax ; No match - don't use card.
jmp CHKRET
GOT_MATCH:
; si = int. vector offset.
xor ax,ax
mov es,ax
mov ax,es:[si + 2] ; Get segment of int. rout.
mov bx,es:[si] ; Get offset " "
sub bx,8 ; minus 8.
mov es,ax
mov ax,es:[bx + 2] ; Get USER_CALL segment
mov dx,es:[bx] ; Get offset.
mov cs:[SDA_SEG],ax
mov cs:[SDA_OFST],dx
mov si,11 ; Get tempo update status.
call DOUC
mov TUP_STATUS,al
cmp al,0 ; Are tempo status updates active ?
jz UPNA ; No
mov si,8 ; Yes - Turn them off.
call DOUC
UPNA:
mov si,6 ; Get port addresses of Midicard
call DOUC
mov PTA,ax
inc ax
mov PTB,ax
inc ax
mov PTC,ax
inc ax
mov PTCNTL,ax
mov ax,1
CHKRET:
pop bp
pop si
pop es
ret
_CHECK4_SDA endp
; SDA_MATCH
;
; This routine looks for the string "SDA " above the interrupt
; location indicated by the vector offset in 'si'.
;
; Returns: ax = 0 No match
; ax = 1 Match
;
; Regs altered ax,bx,es
SDA_MATCH proc near
xor ax,ax
mov es,ax
mov bx,si
mov ax, word ptr es:[bx] + 2
mov bx, word ptr es:[bx]
mov es,ax
cmp byte ptr es:[bx] - 4,'S'
jne matret
cmp byte ptr es:[bx] - 3,'D'
jne matret
cmp byte ptr es:[bx] - 2,'A'
jne matret
cmp byte ptr es:[bx] - 1,' '
jne matret
mov ax,1
matret:
ret
SDA_MATCH endp
page
; _PREP_RET - Prepare to terminate program and return to Promidi.
;
; ******* THIS ROUTINE MUST BE CALLED BEFORE TSR PROGRAM TERMINATION
;
;
; c call prep_ret();
;
; asm call call _prep_ret
; (far)
;
; Regs Altered: ax,bx,cx,dx
_PREP_RET proc far
cmp TUP_STATUS,0 ; Was tempo status update active ?
jz RETRET ; No
push si
mov si,7 ; Yes - re-enable tempo updates.
call DOUC
pop si
RETRET:
ret
_PREP_RET endp
page
; _SDA_GETB - If in sda record mode, get a byte from midi in.
;
; c call c = sda_getb();
;
; asm call call _sda_getb ; Byte or ret. code in ax.
; (far)
;
; RETURNS: byte
; 100H Buffer empty
; 2nnH Buffer overflow (byte in LSB).
;
; Regs Altered: ax,bx,cx,dx
_SDA_GETB proc far
push si
mov si,1
call DOUC
pop si
ret
_SDA_GETB endp
page
; _SDA_PUTB - send a byte (of a complete midi msg.) out midi out.
;
; c call sda_putb(c);
;
; asm call push ax ; Push byte on stack
; (far) call _sda_putb
; add sp,2
;
; Regs Altered: ax,bx,cx,dx
_SDA_PUTB proc far
push bp
mov bp,sp
push si
mov cx,[bp+6] ; Get parameter.
mov si,2
call DOUC
pop si
pop bp
ret
_SDA_PUTB endp
page
; _SDA_RECON - Go into SDA record mode.
;
; c call sda_recon();
;
; asm call call _sda_recon
; (far)
;
; Returns: non-0 No. of bytes allocated to receive buffer.
; 0 Fail - already recording or
; not enough memory.
;
; Regs Altered: ax,bx,cx,dx
_SDA_RECON proc far
mov UREC_MODE,1
push si
mov si,3
call DOUC
pop si
ret
_SDA_RECON endp
page
; _SDA_RECOFF - Leave SDA record mode.
;
; c call sda_recoff();
;
; asm call call _sda_recoff
; (far)
;
; Regs Altered: ax,bx,cx,dx
_SDA_RECOFF proc far
mov UREC_MODE,0
push si
mov si,4
call DOUC
pop si
ret
_SDA_RECOFF endp
page
; _U_SNDB - Send a byte to the Midicard.
;
; c call u_sndb(c);
;
; asm call push ax ; Push byte on stack
; (far) call _u_sndb
; add sp,2
;
;
; Regs Altered: ax,cx,dx
_U_SNDB proc far
push bp
mov bp,sp
mov cx,[bp+6] ; Get parameter.
USND1:
mov dx,PTC
in al,dx
test al,80H ; Output buffer empty ?
jz USND1 ; No - keep trying.
mov dx,PTB
in al,dx
test al,40H ; Can we send Midi data ?
jnz USND1 ; No - keep trying.
mov dx,PTCNTL ; Say its Midi data
mov al,4 ; (not a command)
out dx,al
mov dx,PTA ; Send byte.
mov al,cl
out dx,al
pop bp
ret
_U_SNDB endp
page
; _U_RCVB - If a byte is present, receive a byte from the Midicard
;
; c call c = u_rcvb();
;
; asm call call _u_rcvb ; Byte or ret. code in ax.
; (far)
;
; RETURNS: byte
; 100H No input received
;
; Regs Altered: ax,dx
_U_RCVB proc far
mov dx,PTC
in al,dx
test al,20H ; Look for input
jnz IBFULL
mov ax,100H ; None
jmp URCRET
IBFULL:
mov dx,PTA ; Get byte
in al,dx
xor ah,ah
URCRET:
ret
_U_RCVB endp
page
; _U_TRCV - Test if a byte is present from the Midicard
;
; c call rc = u_trcv();
;
; asm call call _u_trcv ; Ret. code in ax.
; (far)
;
; RETURNS: 0 No input.
; 1 Input present.
;
; Regs Altered: ax,dx
_U_TRCV proc far
mov dx,PTC
in al,dx
test al,20H ; Look for input
jnz UTR1
xor ax,ax
jmp UTRRET
UTR1:
mov ax,1
UTRRET:
ret
_U_TRCV endp
page
; _SDA_UON - Enter Uart Mode
;
; c call rc = sda_uon();
;
; asm call call _sda_uoff ; Return code in ax
; (far)
;
; RETURNS: 0 - FAIL, Promidi is recording or playing, or
; we are in User Record Mode.
; 1 - SUCCESS - in Uart Mode.
;
;
; Regs Altered: ax,bx,cx,dx
_SDA_UON proc far
cmp UREC_MODE,0
jnz UONFAIL
push si
mov si,9
call DOUC
pop si
cmp ax,0
jnz UON2
UONFAIL:
xor ax,ax
jmp UONRET
UON2:
mov dx,PTC
in al,dx
test al,80H
jz UON2
mov dx,PTCNTL
mov al,5
out dx,al
mov dx,PTA
mov al,35
out dx,al
mov ax,1
UONRET:
ret
_SDA_UON endp
page
; _SDA_UOFF - Leave Uart Mode
;
; c call sda_uoff();
;
; asm call call _sda_uoff
; (far)
;
; Regs Altered: ax,bx,cx,dx
_SDA_UOFF proc far
push si
mov si,10
call DOUC
pop si
ret
_SDA_UOFF endp
page
; _SDA_EXEC - Call Promidi's multi-tasking exec.
; This gives Promidi a chance to replenish
; its disk buffers when playing.
;
; c call sda_exec();
;
; asm call call _sda_exec
; (far)
;
; Regs Altered: ax,bx,cx,dx
_SDA_EXEC proc far
push si
mov si,5
call DOUC
pop si
ret
_SDA_EXEC endp
page
; The DOUC sub-routine vectors into the Promidi software.
; The 2-word address must have been set up via a successful
; call to _check4_sda.
DOUC proc near
mov ax,[_SDA_DSEG] ; Get the SDA data seg.
db 9AH
SDA_OFST dw 0 ; USER_CALL offset.
SDA_SEG dw 0 ; USER_CALL segment.
ret
DOUC endp
code ends
END